import { observe } from '../observer/index'
// 属性初始化
export function initState(vm) {
  console.log("initState 开始");
  console.log(vm)
  vm._watchers = [];
  const opts = vm.$options; // 合并后的options
  // 对data进行劫持
  if(opts.data){
    //  如果data存在 执行 initData方法
    initData(vm)
  } else {
    // todo
    // 不存在 执行observe asRootData
    observe(vm._data = {}, true)
  }
  // todo 初始化所有props methods data computed watch computed 
  console.log("initState 结束");
}
//  Vue初始化 状态混入
export function stateMixin(Vue) {
    console.log('stateMixin 开始')
    // todo $data $props 响应式

    // 定义 $set $delete $watch 方法
    console.log('stateMixin 结束')
}
// 对data进行劫持
function initData(vm){
  let data = vm.$options.data
  // 如果data是函数则执行 getData方法 否则返回data或一个空对象
  data = vm._data = typeof data === 'function' ? getData(data,vm) : data || {}
  const keys = Object.keys(data)
  // props methods 是否重名
  let i = keys.length
  while(i--) {
    const key = keys[i]
    // todo 错误处理 属性修正
    // _data代理
    proxy(vm,'_data',key)
  }
  // 数据响应式
  observe(data,true)
}

const sharedPropertyDefinition = {
  enumerable: true,
  configurable: true,
  get: function(){},
  set: function(){},
}

export function proxy (target, sourceKey, key) {
  sharedPropertyDefinition.get = function proxyGetter() {
    return this[sourceKey][key]
  }
  sharedPropertyDefinition.set = function proxySetter(val) {
    this[sourceKey][key] = val
  }
  Object.defineProperty(target, key, sharedPropertyDefinition)
}

export function getData (data, vm) {
  // pushTarget()
  try {
    return data.call(vm)
  }catch(e){
    // 错误处理
    return {}
  }finally {
    // popTarget()
  }
}